[system-updater] Configure public keys from assembly Added a dev key generated by `openssl genpkey -algorithm ed25519 -out manifest_dev_key.pem` The public dev key is included in eng build by default unless overridden in product config. Bug: 441769485 Change-Id: Ia8025c7e6af24bcd81a5118707ccae3394f5550c Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1387005 Fuchsia-Auto-Submit: Sen Jiang <senj@google.com> Commit-Queue: Sen Jiang <senj@google.com> Reviewed-by: Ben Keller <galbanum@google.com> Reviewed-by: Aaron Wood <aaronwood@google.com> Reviewed-by: Aidan Wolter <awolter@google.com>
diff --git a/src/lib/assembly/config_schema/src/platform_settings/swd_config.rs b/src/lib/assembly/config_schema/src/platform_settings/swd_config.rs index 388abf4..dcd52b4 100644 --- a/src/lib/assembly/config_schema/src/platform_settings/swd_config.rs +++ b/src/lib/assembly/config_schema/src/platform_settings/swd_config.rs
@@ -34,6 +34,11 @@ #[serde(skip_serializing_if = "crate::common::is_default")] pub enable_upgradable_packages: bool, + + /// The public keys used to verify ota manifest in packageless updates. + /// Each key must be 32 bytes and encoded as a 64 bytes hex string. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub ota_manifest_public_keys: Vec<String>, } /// The SWD Policies are laid out in
diff --git a/src/lib/assembly/platform_configuration/src/subsystems/swd.rs b/src/lib/assembly/platform_configuration/src/subsystems/swd.rs index c2973a7..e671212 100644 --- a/src/lib/assembly/platform_configuration/src/subsystems/swd.rs +++ b/src/lib/assembly/platform_configuration/src/subsystems/swd.rs
@@ -4,7 +4,7 @@ use crate::subsystems::prelude::*; use anyhow::{Context, Result, anyhow, bail}; -use assembly_config_capabilities::{Config, ConfigValueType}; +use assembly_config_capabilities::{Config, ConfigNestedValueType, ConfigValueType}; use assembly_config_schema::platform_settings::swd_config::{ OtaConfigs, PolicyConfig, PolicyLabels, SwdConfig, UpdateChecker, VerificationFailureAction, }; @@ -12,14 +12,13 @@ use camino::Utf8PathBuf; use std::fs::File; -#[allow(dead_code)] -const FUZZ_PERCENTAGE_RANGE: u32 = 25; -#[allow(dead_code)] -const RETRY_DELAY_SECONDS: u32 = 300; +// openssl pkey -in src/sys/pkg/bin/system-updater/keys/manifest_dev_key.pem -pubout -outform DER | tail -c 32 | xxd -p -c 32 +const OTA_MANIFEST_DEV_PUBLIC_KEY: &str = + "b1d9c9414b0a97a225da46ce6ae05753fa69cf722da706132ced72ccf48213e9"; +const OTA_MANIFEST_PUBLIC_KEY_HEX_LEN: usize = 64; /// SWD Configuration implementation detail which clarifies different subsystem behavior, derived /// from the PolicyLabels -#[allow(dead_code)] #[derive(Debug)] pub struct PolicyLabelDetails { enable_dynamic_configuration: bool, @@ -50,19 +49,6 @@ } } -impl DefaultByBuildType for SwdConfig { - fn default_by_build_type(build_type: &BuildType) -> Self { - SwdConfig { - policy: Some(PolicyLabels::default_by_build_type(build_type)), - update_checker: Some(UpdateChecker::default_by_build_type(build_type)), - on_verification_failure: VerificationFailureAction::default(), - tuf_config_paths: vec![], - include_configurator: false, - enable_upgradable_packages: false, - } - } -} - pub(crate) struct SwdSubsystemConfig; impl DefineSubsystemConfiguration<SwdConfig> for SwdSubsystemConfig { /// Configures the SWD system. If a specific field is not specified, a @@ -128,6 +114,38 @@ Config::new(ConfigValueType::Bool, subsystem_config.enable_upgradable_packages.into()), )?; + let manifest_public_keys = if subsystem_config.ota_manifest_public_keys.is_empty() + && context.build_type == &BuildType::Eng + { + // Include a default dev key in eng builds. + [OTA_MANIFEST_DEV_PUBLIC_KEY].into() + } else { + for key in &subsystem_config.ota_manifest_public_keys { + if key.len() != OTA_MANIFEST_PUBLIC_KEY_HEX_LEN { + bail!( + "OTA manifest public key must be {} hex characters, but {:?} has {}", + OTA_MANIFEST_PUBLIC_KEY_HEX_LEN, + key, + key.len(), + ); + } + } + (&*subsystem_config.ota_manifest_public_keys).into() + }; + + builder.set_config_capability( + "fuchsia.system-updater.ManifestPublicKeys", + Config::new( + ConfigValueType::Vector { + nested_type: ConfigNestedValueType::String { + max_size: OTA_MANIFEST_PUBLIC_KEY_HEX_LEN as u32, + }, + max_count: 10, + }, + manifest_public_keys, + ), + )?; + Ok(()) } } diff --git a/src/recovery/system/meta/core_shards/system_recovery_android.core_shard.cml b/src/recovery/system/meta/core_shards/system_recovery_android.core_shard.cml index 326aee1..624965d 100644 --- a/src/recovery/system/meta/core_shards/system_recovery_android.core_shard.cml +++ b/src/recovery/system/meta/core_shards/system_recovery_android.core_shard.cml
@@ -39,7 +39,10 @@ to: "#system_recovery", }, { - config: [ "fuchsia.recovery.DisplayRotation" ], + config: [ + "fuchsia.recovery.DisplayRotation", + "fuchsia.system-updater.ManifestPublicKeys", + ], from: "parent", to: "#system_recovery", availability: "same_as_target", diff --git a/src/recovery/system/meta/system_recovery_android.cml b/src/recovery/system/meta/system_recovery_android.cml index 422261d..cc34094 100644 --- a/src/recovery/system/meta/system_recovery_android.cml +++ b/src/recovery/system/meta/system_recovery_android.cml
@@ -111,6 +111,11 @@ to: "#pkg-recovery", dependency: "weak", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "parent", + to: "#pkg-recovery", + }, ], expose: [ { diff --git a/src/security/tests/pkg_test/tests/access_ota_blob_as_executable/meta/access_ota_blob_as_executable.cml b/src/security/tests/pkg_test/tests/access_ota_blob_as_executable/meta/access_ota_blob_as_executable.cml index 4f2f969..df9af8a 100644 --- a/src/security/tests/pkg_test/tests/access_ota_blob_as_executable/meta/access_ota_blob_as_executable.cml +++ b/src/security/tests/pkg_test/tests/access_ota_blob_as_executable/meta/access_ota_blob_as_executable.cml
@@ -105,6 +105,16 @@ backing_dir: "tmp", storage_id: "static_instance_id_or_moniker", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + type: "vector", + max_count: 10, + element: { + type: "string", + max_size: 64, + }, + value: [], + }, ], use: [ // Control storage capabilities of this realm. See @@ -136,6 +146,7 @@ { protocol: "fuchsia.update.installer.Installer", from: "#system-updater", + dependency: "weak", }, { protocol: [ @@ -208,6 +219,11 @@ availability: "optional", }, { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "self", + to: "#system-updater", + }, + { directory: "blob-exec", from: "#fshost", as: "blob", diff --git a/src/security/tests/pkg_test/tests/bad_signature_update/meta/bad_signature_update.cml b/src/security/tests/pkg_test/tests/bad_signature_update/meta/bad_signature_update.cml index d73928d..ae50500 100644 --- a/src/security/tests/pkg_test/tests/bad_signature_update/meta/bad_signature_update.cml +++ b/src/security/tests/pkg_test/tests/bad_signature_update/meta/bad_signature_update.cml
@@ -101,6 +101,16 @@ backing_dir: "tmp", storage_id: "static_instance_id_or_moniker", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + type: "vector", + max_count: 10, + element: { + type: "string", + max_size: 64, + }, + value: [], + }, ], use: [ // Control storage capabilities of this realm. See @@ -132,6 +142,7 @@ { protocol: "fuchsia.update.installer.Installer", from: "#system-updater", + dependency: "weak", }, ], offer: [ @@ -198,6 +209,11 @@ availability: "optional", }, { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "self", + to: "#system-updater", + }, + { directory: "blob-exec", from: "#fshost", as: "blob", diff --git a/src/sys/core/meta/core.root_shard.cml b/src/sys/core/meta/core.root_shard.cml index 25e1b89..30fdfee 100644 --- a/src/sys/core/meta/core.root_shard.cml +++ b/src/sys/core/meta/core.root_shard.cml
@@ -63,6 +63,7 @@ "fuchsia.session.window.Collection", "fuchsia.session.window.InitialElementUrl", "fuchsia.session.window.InitialViewIdAnnotation", + "fuchsia.system-updater.ManifestPublicKeys", "fuchsia.time.config.HasWakeAlarms", "fuchsia.time.config.WritableUTCTime", "fuchsia.ui.AttachA11yView",
diff --git a/src/sys/pkg/bin/system-updater/keys/manifest_dev_key.pem b/src/sys/pkg/bin/system-updater/keys/manifest_dev_key.pem new file mode 100644 index 0000000..da9b4ff --- /dev/null +++ b/src/sys/pkg/bin/system-updater/keys/manifest_dev_key.pem
@@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIHF6l/uIsoxSPqvEgnyczWwdNIB5w9Tao8Ijp6Cv9OLT +-----END PRIVATE KEY-----
diff --git a/src/sys/pkg/bin/system-updater/meta/system-updater-common.shard.cml b/src/sys/pkg/bin/system-updater/meta/system-updater-common.shard.cml index 78e4aa7..e94f670 100644 --- a/src/sys/pkg/bin/system-updater/meta/system-updater-common.shard.cml +++ b/src/sys/pkg/bin/system-updater/meta/system-updater-common.shard.cml
@@ -44,6 +44,16 @@ rights: [ "r*" ], path: "/blob", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + key: "manifest_public_keys", + type: "vector", + max_count: 10, + element: { + type: "string", + max_size: 64, // hex encoded 32 bytes key + }, + }, ], expose: [ { diff --git a/src/sys/pkg/bin/system-updater/meta/system_updater.core_shard.cml b/src/sys/pkg/bin/system-updater/meta/system_updater.core_shard.cml index c660d79..8ad4f56 100644 --- a/src/sys/pkg/bin/system-updater/meta/system_updater.core_shard.cml +++ b/src/sys/pkg/bin/system-updater/meta/system_updater.core_shard.cml
@@ -54,5 +54,10 @@ from: "self", to: "#system-update", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "parent", + to: "#system-update", + }, ], } diff --git a/src/sys/pkg/bin/system-updater/meta/system_updater.system_update_shard.cml b/src/sys/pkg/bin/system-updater/meta/system_updater.system_update_shard.cml index 476d864..4f4a6280 100644 --- a/src/sys/pkg/bin/system-updater/meta/system_updater.system_update_shard.cml +++ b/src/sys/pkg/bin/system-updater/meta/system_updater.system_update_shard.cml
@@ -63,6 +63,11 @@ from: "parent", to: "#system-updater", }, + { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "parent", + to: "#system-updater", + }, ], expose: [ { diff --git a/src/sys/pkg/lib/isolated-swd/BUILD.gn b/src/sys/pkg/lib/isolated-swd/BUILD.gn index 4d7b18a..1e47ef3 100644 --- a/src/sys/pkg/lib/isolated-swd/BUILD.gn +++ b/src/sys/pkg/lib/isolated-swd/BUILD.gn
@@ -37,6 +37,7 @@ "//src/lib/fuchsia-component-test", "//src/lib/fuchsia-url", "//src/storage/fxfs/fidl/fuchsia.fxfs:fuchsia.fxfs_rust", + "//src/sys/lib/cm_rust", "//src/sys/lib/fidl-fuchsia-pkg-ext", "//src/sys/pkg/lib/fuchsia-merkle", "//src/sys/pkg/lib/fuchsia-pkg-testing",
diff --git a/src/sys/pkg/lib/isolated-swd/src/updater.rs b/src/sys/pkg/lib/isolated-swd/src/updater.rs index 6125a9b..6fe37b2 100644 --- a/src/sys/pkg/lib/isolated-swd/src/updater.rs +++ b/src/sys/pkg/lib/isolated-swd/src/updater.rs
@@ -381,6 +381,24 @@ ) .await .unwrap(); + realm_builder + .add_capability(cm_rust::CapabilityDecl::Config(cm_rust::ConfigurationDecl { + name: "fuchsia.system-updater.ManifestPublicKeys".parse().unwrap(), + value: Vec::<String>::new().into(), + })) + .await + .unwrap(); + realm_builder + .add_route( + Route::new() + .capability(Capability::configuration( + "fuchsia.system-updater.ManifestPublicKeys", + )) + .from(Ref::self_()) + .to(&system_updater), + ) + .await + .unwrap(); // Make sure the component under test can log. realm_builder diff --git a/src/sys/pkg/meta/pkg-recovery.cml b/src/sys/pkg/meta/pkg-recovery.cml index c13cd02..c564026 100644 --- a/src/sys/pkg/meta/pkg-recovery.cml +++ b/src/sys/pkg/meta/pkg-recovery.cml
@@ -87,6 +87,11 @@ to: "#pkg-cache", }, { + config: "fuchsia.system-updater.ManifestPublicKeys", + from: "parent", + to: "#system-updater", + }, + { // Needed for passing repository configs to pkg-resolver directory: "config-data", from: "parent", diff --git a/src/sys/pkg/tests/isolated-ota/BUILD.gn b/src/sys/pkg/tests/isolated-ota/BUILD.gn index 92789cb..25dac60 100644 --- a/src/sys/pkg/tests/isolated-ota/BUILD.gn +++ b/src/sys/pkg/tests/isolated-ota/BUILD.gn
@@ -20,6 +20,7 @@ "//src/lib/fuchsia-sync", "//src/lib/fuchsia-url", "//src/storage/lib/vfs/rust:vfs", + "//src/sys/lib/cm_rust", "//src/sys/lib/fidl-fuchsia-pkg-ext", "//src/sys/pkg/lib/fuchsia-hash", "//src/sys/pkg/lib/fuchsia-pkg-testing",
diff --git a/src/sys/pkg/tests/isolated-ota/src/lib.rs b/src/sys/pkg/tests/isolated-ota/src/lib.rs index 6704fb0..661cef4 100644 --- a/src/sys/pkg/tests/isolated-ota/src/lib.rs +++ b/src/sys/pkg/tests/isolated-ota/src/lib.rs
@@ -297,6 +297,25 @@ .await .unwrap(); + realm_builder + .add_capability(cm_rust::CapabilityDecl::Config(cm_rust::ConfigurationDecl { + name: "fuchsia.system-updater.ManifestPublicKeys".parse().unwrap(), + value: Vec::<String>::new().into(), + })) + .await + .unwrap(); + realm_builder + .add_route( + Route::new() + .capability(Capability::configuration( + "fuchsia.system-updater.ManifestPublicKeys", + )) + .from(Ref::self_()) + .to(&pkg_component), + ) + .await + .unwrap(); + let channel_clone = params.channel.clone(); let realm_instance = realm_builder.build().await.unwrap(); diff --git a/src/sys/pkg/tests/omaha-client/src/lib.rs b/src/sys/pkg/tests/omaha-client/src/lib.rs index 50a8074..1c9bcf8 100644 --- a/src/sys/pkg/tests/omaha-client/src/lib.rs +++ b/src/sys/pkg/tests/omaha-client/src/lib.rs
@@ -594,6 +594,24 @@ ) .await .unwrap(); + builder + .add_capability(cm_rust::CapabilityDecl::Config(cm_rust::ConfigurationDecl { + name: "fuchsia.system-updater.ManifestPublicKeys".parse().unwrap(), + value: Vec::<String>::new().into(), + })) + .await + .unwrap(); + builder + .add_route( + Route::new() + .capability(Capability::configuration( + "fuchsia.system-updater.ManifestPublicKeys", + )) + .from(Ref::self_()) + .to(&system_updater), + ) + .await + .unwrap(); } else { builder .add_route( diff --git a/src/sys/pkg/tests/system-updater/BUILD.gn b/src/sys/pkg/tests/system-updater/BUILD.gn index b43fe4c..26947f0 100644 --- a/src/sys/pkg/tests/system-updater/BUILD.gn +++ b/src/sys/pkg/tests/system-updater/BUILD.gn
@@ -28,6 +28,7 @@ "//src/lib/fuchsia-sync", "//src/lib/fuchsia-url", "//src/storage/fxfs/fidl/fuchsia.fxfs:fuchsia.fxfs_rust", + "//src/sys/lib/cm_rust", "//src/sys/lib/fidl-fuchsia-pkg-ext", "//src/sys/pkg/fidl/fuchsia.update.installer:fuchsia.update.installer_rust", "//src/sys/pkg/lib/fidl-fuchsia-update-installer-ext",
diff --git a/src/sys/pkg/tests/system-updater/src/lib.rs b/src/sys/pkg/tests/system-updater/src/lib.rs index cff4427..1d52fd5 100644 --- a/src/sys/pkg/tests/system-updater/src/lib.rs +++ b/src/sys/pkg/tests/system-updater/src/lib.rs
@@ -586,11 +586,22 @@ .set_config_value(&system_updater, "allow_packageless_update", true.into()) .await .unwrap(); + builder - .set_config_value( - &system_updater, - "manifest_public_keys", - vec![MANIFEST_PUBLIC_KEY].into(), + .add_capability(cm_rust::CapabilityDecl::Config(cm_rust::ConfigurationDecl { + name: "fuchsia.system-updater.ManifestPublicKeys".parse().unwrap(), + value: vec![MANIFEST_PUBLIC_KEY].into(), + })) + .await + .unwrap(); + builder + .add_route( + Route::new() + .capability(Capability::configuration( + "fuchsia.system-updater.ManifestPublicKeys", + )) + .from(Ref::self_()) + .to(&system_updater), ) .await .unwrap();